package com.doraro.platform.module.device.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.doraro.platform.common.beans.params.PageParam;
import com.doraro.platform.common.beans.params.ValidateGroups;
import com.doraro.platform.common.beans.response.PageView;
import com.doraro.platform.common.utils.Result;
import com.doraro.platform.common.utils.ShiroUserUtil;
import com.doraro.platform.module.device.model.entity.RepairAdvice;
import com.doraro.platform.module.device.model.entity.RepairOrder;
import com.doraro.platform.module.device.model.param.RepairDeviceParam;
import com.doraro.platform.module.device.model.param.cond.OrderCond;
import com.doraro.platform.module.device.service.IRepairAdviceService;
import com.doraro.platform.module.device.service.IRepairOrderService;
import com.doraro.platform.module.user.service.ISysJobService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

import static com.doraro.platform.common.utils.Constant.ADMIN_NAME;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author doraro
 * @since 2019-04-21
 */
@RestController
@RequestMapping("/api/order")
@Api(description = "维修单相关接口", tags = "order")
public class RepairOrderRestController {
    private final IRepairOrderService orderService;
    private final IRepairAdviceService adviceService;
    private final ISysJobService jobService;

    @Autowired
    public RepairOrderRestController(IRepairOrderService orderService, IRepairAdviceService adviceService, ISysJobService jobService) {
        this.orderService = orderService;
        this.adviceService = adviceService;
        this.jobService = jobService;
    }


    @PostMapping("/create")
    @ApiOperation("用户创建维修单")
    @RequiresPermissions("order:create")
    public Result createRepairOrder(@Validated(ValidateGroups.Create.class) @RequestBody RepairDeviceParam param) {
        if (checkDeviceParam(param)) {
            return new Result().error(HttpStatus.BAD_REQUEST, "故障时间不能再生产时间之前!");
        }
        final String id = orderService.createOrder(param, ShiroUserUtil.getCurrentId());
        return new Result().ok().addData("orderId", id);
    }

    /**
     * 仅未受理时刻修改
     *
     * @param param
     * @param orderId
     * @return
     */
    @PutMapping("/{orderId}")
    @ApiOperation("用户修改维修单信息")
    @RequiresPermissions("order:update")
    public Result updateRepairOrder(@Validated(ValidateGroups.Update.class) @RequestBody RepairDeviceParam param, @PathVariable String orderId) {
        if (checkDeviceParam(param)) {
            return new Result().error(HttpStatus.BAD_REQUEST, "故障时间不能再生产时间之前!");
        }
        orderService.updateByOrderId(orderId, param, ShiroUserUtil.getCurrentId());
        return new Result().ok();
    }

    /**
     * 撤销故障设备信息，仅在用户没有选择工程师上可以，
     * TODO:否则需要经过管理员同意才能撤销
     * 附带原因
     */
    @DeleteMapping("/{orderId}")
    @ApiOperation("用户撤销维修单")
    @RequiresPermissions("order:cancel")
    public Result rejectOrder(@PathVariable String orderId) {
        orderService.rejectOrder(ShiroUserUtil.getCurrentId(), orderId);
        return new Result().ok();
    }

    //TODO:返回相关解决案例
    @GetMapping("/{orderId}")
    @ApiOperation("查看设备维修单信息信息")
    @RequiresPermissions("order:detail")
    public Result viewOrderByOrderId(@PathVariable String orderId) {
        RepairOrder detail = orderService.getById(orderId);
        return new Result().ok().addData("order", detail);
    }

    /**
     * 非admin只能查自己
     * @param pageParam
     * @return
     */
    @GetMapping("/page")
    @ApiOperation("分页查看设备维修单信息")
    @RequiresPermissions("order:page")
    public Result viewOrderByPage(PageParam<RepairOrder> pageParam, OrderCond searchParam) {
        final Page<RepairOrder> param = pageParam.toPage();
        final String id = ShiroUserUtil.getCurrentId();
        final LambdaQueryWrapper<RepairOrder> wrapper = searchParam.condition()
                .eq(!ShiroUserUtil.is(ADMIN_NAME), RepairOrder::getCreateUserId, id);
        return new Result().ok().addData("page", new PageView(orderService.page(param, wrapper)));
    }

    @GetMapping("/eng/page")
    @ApiOperation("分页查看未解决维修单的信息")
    @RequiresPermissions("order:eng:page")
    public Result getEngOrderByPage(PageParam<RepairOrder> pageParam, RepairOrder searchParam) {
        final Page<RepairOrder> param = pageParam.toPage();

        final IPage<RepairOrder> orderByPage = orderService.getUnresolvedOrderByPage(param, searchParam);
        final List<String> orderIds = orderByPage.getRecords().stream().map(RepairOrder::getId).collect(Collectors.toList());
        List<RepairAdvice> advices = null;
        if (!orderIds.isEmpty()) {
            advices = adviceService.lambdaQuery()
                    .eq(RepairAdvice::getEngineerId, ShiroUserUtil.getCurrentId())
                    .in(RepairAdvice::getOrderId, orderIds).list();
        }
        return new Result().ok()
                .addData("page", new PageView(orderByPage))
                .addData("advices", advices);
    }




    @PostMapping("/accept")
    @ApiOperation("用户接受工程师发送的维修请求")
    @RequiresPermissions("order:accept")
    @Transactional(rollbackFor = Exception.class)
    public Result completeOrder(@RequestParam String orderId) {
        orderService.confirmCompleteOrder(orderId);

        return new Result().ok();
    }

    private boolean checkDeviceParam(RepairDeviceParam param) {
        return param.getBreakdownTime().isBefore(param.getProductionTime());
    }
}

